package vip.xiaonuo.core.util;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import okhttp3.*;
import org.apache.commons.lang3.StringUtils;
import vip.xiaonuo.core.exception.ServiceException;
import vip.xiaonuo.core.pojo.httpclient.ReturnJson;
import vip.xiaonuo.core.pojo.httpclient.ReturnJsonRemote;

import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.Map;
import java.util.Objects;

public class OkHttpUtils {


  /**
   * 列表查询
   *
   * @param url    客户端api url
   * @param params 参数
   * @return
   */
  public static Object[] getList(String url, Map<String, Object> params) {
    OkHttpClient okHttpClient = new OkHttpClient();
    Request request = new Request.Builder().url(url + "?" + spliceParams(params)).addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8").get().build();
    try {
      Response response = okHttpClient.newCall(request).execute();
      return new Object[]{resStrToJson(response)};
    } catch (Exception e) {
      e.printStackTrace();
      ReturnJson rj = new ReturnJson();
      rj.setMsg("连接超时");
      return new Object[]{rj};
    }
  }


  /**
   * Post请求发送JSON数据
   */
  public static String postJsonParams(String url, Map<String, Object> params) throws IOException {
    OkHttpClient okHttpClient = new OkHttpClient();
    RequestBody requestBody = RequestBody.create(MediaType.parse("application/json; charset=utf-8"), JSON.toJSONString(params));
    Request request = new Request.Builder().url(url).post(requestBody).build();
    Response response = null;
    response = okHttpClient.newCall(request).execute();
    if (Objects.nonNull(response) && response.isSuccessful()) {
      return response.body().string();
    } else {
      throw new RuntimeException("请求失败！[" + response.body() + "]");
    }
  }

  /**
   * post方式异步调用
   *
   * @param url  请求url
   * @param json 传递参数
   * @return
   */
  public static String rawRequest(String url, String json) {
    OkHttpClient client = new OkHttpClient();
    MediaType JSON = MediaType.parse("application/json; charset=utf-8");//数据类型为json格式，
    RequestBody body = RequestBody.create(JSON, json);
    Request request = new Request.Builder().url(url).post(body).build();
    client.newCall(request).enqueue(new Callback() {
      @Override
      public void onFailure(Call call, IOException e) {
        //此处省略回调方法。
      }

      @Override
      public void onResponse(Call call, Response response) throws IOException {
        //此处省略回调方法。
      }
    });
    return "";
  }

  /**
   * 同步调用 异常：error=unexpected end of stream on Connection 解决：.addHeader("Connection","close"); 参考：https://blog.csdn.net/q9104422999/article/details/85262579
   *
   * @param reqType 请求方式 GET/POST/PUT/DELETE
   * @param url     请求url
   * @param params  传递参数
   * @return
   */
  public static ReturnJson commonRequest(ReqType reqType, String url, Map<String, Object> params) {
    OkHttpClient okHttpClient = new OkHttpClient();
    MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
    if (params != null) {
      for (String key : params.keySet()) {
        if (params.get(key) != null) {
          body.addFormDataPart(key, String.valueOf(params.get(key)));
        }
      }
    }

    Request.Builder builder = new Request.Builder().url(url).addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8").addHeader("Connection", "close");
    Request request;
    switch (reqType) {
      case GET:
        builder.url(url + "?" + UrlUtils.getURLEncoderString(spliceParams(params)));
        request = builder.get().build();
        break;
      case PUT:
        request = builder.put(body.build()).build();
        break;
      case POST:
        request = builder.post(body.build()).build();
        break;
      case DELETE:
        request = builder.delete(body.build()).build();
        break;
      default:
        request = builder.get().build();
        break;
    }
    try {
      Response response = okHttpClient.newCall(request).execute();
      return resStrToJson(response);
    } catch (Exception e) {
      ReturnJson rj = new ReturnJson();
      if (e.getMessage().equals("Cannot assign requested address: connect")) {
        //3:接口请求失败,请检查设备IP是否正确(无此IP的设备)
        rj.setCode("3");
        rj.setMsg("设备连接失败,请检查设备IP是否正确");
      } else if (e.getMessage().equals("Failed to connect to /" + StringUtils.substringBeforeLast(url.substring(7), "/"))) {
        //5:接口请求失败,请检查设备IP是否正确(设备断线)
        rj.setCode("5");
        rj.setMsg("设备断线或网络异常");
      } else {
        //4：其他异常
        rj.setCode("4");
        rj.setMsg(/*"系统异常，请稍后再试:"+*/e.getMessage());
      }
      return rj;
    }
  }


  public static <T> T requestDevice(ReqType reqType, String url, Map<String, Object> params, Class<T> returnType) throws Exception {
    OkHttpClient okHttpClient = new OkHttpClient();
    MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
    if (params != null) {
      for (String key : params.keySet()) {
        if (params.get(key) != null) {
          body.addFormDataPart(key, String.valueOf(params.get(key)));
        }
      }
    }
    Request.Builder builder = new Request.Builder().url(url).addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8").addHeader("Connection", "close");
    Request request;
    switch (reqType) {
      case GET:
        builder.url(url + "?" + UrlUtils.getURLEncoderString(spliceParams(params)));
        request = builder.get().build();
        break;
      case PUT:
        request = builder.put(body.build()).build();
        break;
      case POST:
        request = builder.post(body.build()).build();
        break;
      case DELETE:
        request = builder.delete(body.build()).build();
        break;
      default:
        request = builder.get().build();
        break;
    }
    Response response = okHttpClient.newCall(request).execute();
     if (response != null && response.body() != null) {
      String res = response.body().string();
      return JSON.parseObject(res, returnType);
    } else {
      throw new ServiceException(500, "没有任何返回信息!");
    }

  }


  public static String spliceParams(Map<String, Object> params) {
    if (params == null || params.size() <= 0) {
      return "";
    }
    StringBuilder content = new StringBuilder();
    Iterator<Map.Entry<String, Object>> iterator = params.entrySet().iterator();
    while (iterator.hasNext()) {
      Map.Entry<String, Object> entry = iterator.next();
      content.append(entry.getKey()).append("=").append(entry.getValue());
      if (iterator.hasNext()) {
        content.append("&");
      }
    }
    return content.toString();
  }


  /**
   * 将返回的response转化成AjaxJSON
   *
   * @param response
   * @return
   * @throws IOException
   */
  public static ReturnJson resStrToJson(Response response) throws IOException {
    ReturnJson returnJson;
    String res = response.body().string();
    if (res == null || res.length() < 1) {
      returnJson = new ReturnJson();
      returnJson.setCode("1");
      returnJson.setMsg("无任何数据");
      return returnJson;
    }
    returnJson = JSONObject.parseObject(res, ReturnJson.class);
    if (returnJson == null) {
      returnJson = new ReturnJson();
      returnJson.setCode("1");
      returnJson.setMsg("json转化错误");
      return returnJson;
    }


    return returnJson;
  }


  public static ReturnJsonRemote resStrToJsonRemote(Response response) throws IOException {
    ReturnJsonRemote returnJson;
    String res = response.body().string();
    if (res == null || res.length() < 1) {
      returnJson = new ReturnJsonRemote();
      returnJson.setCode(1);
      returnJson.setMsg("无任何数据");
      return returnJson;
    }
    returnJson = JSONObject.parseObject(res, ReturnJsonRemote.class);
    if (returnJson == null) {
      returnJson = new ReturnJsonRemote();
      returnJson.setCode(1);
      returnJson.setMsg("json转化错误");
      return returnJson;
    }


    return returnJson;
  }

  public enum ReqType {
    GET, POST, PUT, DELETE
  }

  /**
   * 专网健康码查询接口
   *
   * @param reqType
   * @param url
   * @param params
   * @return
   */
  public static String commonRequest1(ReqType reqType, String url, Map<String, Object> params) {
    OkHttpClient okHttpClient = new OkHttpClient();
    MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
    if (params != null) {
      for (String key : params.keySet()) {
        if (params.get(key) != null) {
          body.addFormDataPart(key, String.valueOf(params.get(key)));
        }
      }
    }
    Request.Builder builder = new Request.Builder().url(url).addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8").addHeader("Connection", "close");
    Request request;
    switch (reqType) {
      case GET:
        builder.url(url + "?" + UrlUtils.getURLEncoderString(spliceParams(params)));
        request = builder.get().build();
        break;
      case PUT:
        request = builder.put(body.build()).build();
        break;
      case POST:
        request = builder.post(body.build()).build();
        break;
      case DELETE:
        request = builder.delete(body.build()).build();
        break;
      default:
        request = builder.get().build();
        break;
    }
    Response response = null;
    String result = null;
    try {
      response = okHttpClient.newCall(request).execute();
      if (response != null && response.body() != null) {
        //return JSONObject.parseObject(response.body().string(), (Type) ReturnResult.class);
        //
        result = response.body().string();
        System.out.println("if:" + result);
      } else {
        System.out.println("else:" + response.body().string());
      }
      return result;
    } catch (IOException e) {
      e.printStackTrace();
      return e.getMessage();
    }
  }

  /**
   * 人证记录上传
   *
   * @param reqType 数据提交方式
   * @param url     url
   * @param params  参数
   * @param file    抓拍照
   * @return
   */
  public static ReturnJson commonRequest(ReqType reqType, String url, Map<String, Object> params, File file) {
    OkHttpClient okHttpClient = new OkHttpClient();
    MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
    if (params != null) {
      for (String key : params.keySet()) {
        if (params.get(key) != null) {
          //抓拍照
          if (file != null && "image".equals(key)) {
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
            body.addFormDataPart("image1", String.valueOf(params.get(key)), fileBody);
          }
          body.addFormDataPart(key, String.valueOf(params.get(key)));
        }
      }
    }
    Request.Builder builder = new Request.Builder().url(url).addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8").addHeader("Connection", "close");
    Request request;
    switch (reqType) {
      case GET:
        builder.url(url + "?" + UrlUtils.getURLEncoderString(spliceParams(params)));
        request = builder.get().build();
        break;
      case PUT:
        request = builder.put(body.build()).build();
        break;
      case POST:
        request = builder.post(body.build()).build();
        break;
      case DELETE:
        request = builder.delete(body.build()).build();
        break;
      default:
        request = builder.get().build();
        break;
    }
    try {
      Response response = okHttpClient.newCall(request).execute();
      return resStrToJson(response);
    } catch (Exception e) {
      ReturnJson rj = new ReturnJson();
      if (e.getMessage().equals("Cannot assign requested address: connect")) {
        //3:接口请求失败,请检查设备IP是否正确(无此IP的设备)
        rj.setCode("3");
        rj.setMsg("设备连接失败,请检查设备IP是否正确");
      } else if (e.getMessage().equals("Failed to connect to /" + StringUtils.substringBeforeLast(url.substring(7), "/"))) {
        //5:接口请求失败,请检查设备IP是否正确(设备断线)
        rj.setCode("5");
        rj.setMsg("设备断线或网络异常");
      } else {
        //4：其他异常
        rj.setCode("4");
        rj.setMsg(/*"系统异常，请稍后再试:"+*/e.getMessage());
      }
      return rj;
    }
  }


  public static ReturnJson commonRequest(ReqType reqType, String url, Map<String, Object> params, File file, File file1, String dataType) {
    OkHttpClient okHttpClient = new OkHttpClient().newBuilder().build();
    MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
    if (params != null) {
      for (String key : params.keySet()) {
        if (params.get(key) != null) {
          //证件照
          if (file != null && "recordImg".equals(key)) {
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
            body.addFormDataPart("recordImg", String.valueOf(params.get(key)), fileBody);
          }
          //抓拍照
          if (file1 != null && "idCardImg".equals(key)) {
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file1);
            body.addFormDataPart("idCardImg", String.valueOf(params.get(key)), fileBody);
          }
          body.addFormDataPart(key, String.valueOf(params.get(key)));
        }
      }
    }
    if ("pda".equals(dataType)) {
      RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), "");
      body.addFormDataPart("image1", String.valueOf(params.get("idCardImg")), fileBody);
      RequestBody fileBody2 = RequestBody.create(MediaType.parse("application/octet-stream"), "");
      body.addFormDataPart("image2", String.valueOf(params.get("image")), fileBody2);
    }
    Request.Builder builder = new Request.Builder().url(url).addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8").addHeader("Connection", "close");
    Request request;
    switch (reqType) {
      case GET:
        builder.url(url + "?" + UrlUtils.getURLEncoderString(spliceParams(params)));
        request = builder.get().build();
        break;
      case PUT:
        request = builder.put(body.build()).build();
        break;
      case POST:
        request = builder.post(body.build()).build();
        break;
      case DELETE:
        request = builder.delete(body.build()).build();
        break;
      default:
        request = builder.get().build();
        break;
    }
    try {
      Response response = okHttpClient.newCall(request).execute();
      return resStrToJson(response);
    } catch (Exception e) {
      ReturnJson rj = new ReturnJson();
      if (e.getMessage().equals("Cannot assign requested address: connect")) {
        //3:接口请求失败,请检查设备IP是否正确(无此IP的设备)
        rj.setCode("3");
        rj.setMsg("设备连接失败,请检查设备IP是否正确");
      } else if (e.getMessage().equals("Failed to connect to /" + StringUtils.substringBeforeLast(url.substring(7), "/"))) {
        //5:接口请求失败,请检查设备IP是否正确(设备断线)
        rj.setCode("5");
        rj.setMsg("设备断线或网络异常");
      } else {
        //4：其他异常
        rj.setCode("4");
        rj.setMsg(/*"系统异常，请稍后再试:"+*/e.getMessage());
      }
      return rj;
    }
  }


  /**
   * 人证记录上传
   *
   * @param reqType 数据提交方式
   * @param url     url
   * @param params  参数
   * @param file    证件照
   * @param file1   抓拍照
   * @return
   */
  public static ReturnJsonRemote commonRequest(ReqType reqType, String url, Map<String, Object> params, File file, File file1) {
    OkHttpClient okHttpClient = new OkHttpClient();
    MediaType mediaType = MediaType.parse("application/x-www-form-urlencoded; charset=utf-8");
    MultipartBody.Builder body = new MultipartBody.Builder().setType(MultipartBody.FORM);
    if (params != null) {
      for (String key : params.keySet()) {
        if (params.get(key) != null) {
          //证件照
          if (file != null && file.exists()&&"idCardImg".equals(key)) {
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file);
            body.addFormDataPart("idCardImg", String.valueOf(params.get(key)), fileBody);
          }
          //抓拍照
          if (file1 != null&&file1.exists() && "recordImg".equals(key)) {
            RequestBody fileBody = RequestBody.create(MediaType.parse("application/octet-stream"), file1);
            body.addFormDataPart("recordImg", String.valueOf(params.get(key)), fileBody);
          }
          body.addFormDataPart(key, String.valueOf(params.get(key)));
        }
      }
    }
    Request.Builder builder = new Request.Builder().url(url).addHeader("Content-Type", "application/x-www-form-urlencoded; charset=utf-8").addHeader("Connection", "close");
    Request request;
    switch (reqType) {
      case GET:
        builder.url(url + "?" + UrlUtils.getURLEncoderString(spliceParams(params)));
        request = builder.get().build();
        break;
      case PUT:
        request = builder.put(body.build()).build();
        break;
      case POST:
        request = builder.post(body.build()).build();
        break;
      case DELETE:
        request = builder.delete(body.build()).build();
        break;
      default:
        request = builder.get().build();
        break;
    }
    try {
      Response response = okHttpClient.newCall(request).execute();
      return resStrToJsonRemote(response);
    } catch (Exception e) {
      ReturnJsonRemote rj = new ReturnJsonRemote();
      if (e.getMessage().equals("Cannot assign requested address: connect")) {
        //3:接口请求失败,请检查设备IP是否正确(无此IP的设备)
        rj.setCode(3);
        rj.setMsg("设备连接失败,请检查设备IP是否正确");
      } else if (e.getMessage().equals("Failed to connect to /" + StringUtils.substringBeforeLast(url.substring(7), "/"))) {
        //5:接口请求失败,请检查设备IP是否正确(设备断线)
        rj.setCode(5);
        rj.setMsg("设备断线或网络异常");
      } else {
        //4：其他异常
        rj.setCode(4);
        rj.setMsg(/*"系统异常，请稍后再试:"+*/e.getMessage());
      }
      return rj;
    }
  }

}
